import React, { useState, useEffect, useContext } from 'react';

// 定义一个 ErrorBoundary 组件
const ErrorBoundary = ({ children }) => {
  const [hasError, setHasError] = useState(false);
  const [error, setError] = useState(null);
  const [errorInfo, setErrorInfo] = useState(null);

  // 初始化一个状态来跟踪是否应该忽略错误（用于避免在卸载组件时设置状态导致的警告）
  const isMounted = useRef(true);

  useEffect(() => {
    // 清理函数，设置 isMounted 为 false
    return () => {
      isMounted.current = false;
    };
  }, []);

  // 错误边界的 static getDerivedStateFromError 方法的功能：更新 state 以触发回退 UI 的渲染
  const handleError = (error, errorInfo) => {
    // 仅在组件挂载时更新状态
    if (isMounted.current) {
      setHasError(true);
      setError(error);
      setErrorInfo(errorInfo);
    }
    // 你还可以将错误日志发送到服务器等
  };

  // 使用 React 的 componentDidCatch 生命周期方法的功能：捕获子组件树中的错误
  const didCatch = (error, errorInfo) => {
    // 调用 handleError 方法来处理错误
    handleError(error, errorInfo);
  };

  // 注意：在函数组件中，我们无法直接使用 componentDidCatch，但我们可以利用 Error Boundary 的概念通过其他方式实现错误捕获。
  // 然而，在实际的函数式 Error Boundary 实现中，我们通常不会直接使用 didCatch 这样的函数，
  // 因为函数组件本身不直接支持错误边界的捕获机制。相反，我们会利用 context 或其他技术来间接实现。
  // 但为了说明目的，这里假设有一个机制来触发 didCatch（在实际应用中，这通常是通过包裹子组件并监听错误事件来实现的）。

  if (hasError) {
    // 如果发生错误，显示回退 UI
    return <h1>Something went wrong.</h1>;
  }

  // 否则，正常渲染子组件，并假设有一个机制来捕获子组件中的错误（在实际应用中需要额外实现）
  return children; 
  // 注意：这里的 children 渲染逻辑需要配合实际的错误捕获机制来使用，否则错误不会被捕获。
};

// 注意：上面的代码示例并不是一个完整的函数式 Error Boundary 实现，
// 因为它缺少了实际的错误捕获机制。在真实场景中，你需要结合 context、error boundaries 的概念以及可能的第三方库来实现完整的错误捕获和回退 UI 渲染。

// 一个更实际的做法是使用现有的第三方库（如 react-error-boundary）或结合 context 创建一个自定义的错误捕获系统。

export default ErrorBoundary;
